/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package tetris.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import tetris.model.Model;
import tetris.model.events.FigureActionEvent;
import tetris.model.events.FigureActionListener;
import tetris.model.events.GlassEvent;
import tetris.model.events.GlassListener;
import tetris.model.navigation.Direction;

/**
 *
 * @author vadim
 */
public class GameFieldPanel extends JPanel implements KeyListener,FigureActionListener,
               GlassListener {
    private Model _model;
    private static final int CELL_SIZE = 30;
    private static final int GAP = 1;
    private static final Color BACKGROUND_COLOR = Color.GRAY;
    private static final Color GRID_COLOR = Color.BLACK;
    private int _width;
    private int _height;
     public GameFieldPanel(Model model){
        _model = model;       
        // Инициализация графики
        _width = 2*GAP + CELL_SIZE * (_model.glass().width()+2+_model.nextFigureWidget().width());
        _height = 2*GAP + CELL_SIZE * (_model.glass().height() + 2);
        setPreferredSize(new Dimension(_width, _height));
        setBackground(Color.RED); 
        addKeyListener(this);
        _model.glass().currentFigure().addListener(this);
        _model.judge().setPanel(this);
        _model.glass().addListener(this);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        // Отрисовка фона
        int width  = getWidth();
        int height = getHeight();
        g.setColor(BACKGROUND_COLOR);
        g.fillRect(0, 0, CELL_SIZE*_model.glass().width() + GAP, 
                   CELL_SIZE*_model.glass().height() + GAP);
        g.fillRect(CELL_SIZE*(_model.glass().width()+1) + GAP, 
                   CELL_SIZE, CELL_SIZE*(_model.nextFigureWidget().width()) + GAP, 
                   CELL_SIZE*_model.nextFigureWidget().height() + GAP);
        g.fillRect(CELL_SIZE*(_model.glass().width()+1) + GAP,
                   (CELL_SIZE/2)*(_model.nextFigureWidget().height()*2 +3), CELL_SIZE*5 + GAP, 
                   CELL_SIZE + GAP);
        g.setColor(Color.BLACK);   // восстнанваливаем цвет пера
              
        // Отрисовка сетки
        drawGrid(g);
        g.drawRect(CELL_SIZE*(_model.glass().width()+1) + GAP,
                   (CELL_SIZE/2)*(_model.nextFigureWidget().height()*2 +3), CELL_SIZE*5 + GAP, 
                   CELL_SIZE + GAP);
        _model.nextFigureWidget().currentFigure().draw(g);
        _model.glass().notEndedLines().draw(g);
        _model.glass().currentFigure().draw(g);
        for (int i = 0; i < _model.glass().secondFigures().size(); i++) {
            _model.glass().secondFigures().get(i).draw(g);
        }
       g.drawString("Score: "+_model.score(),CELL_SIZE*(_model.glass().width()+1)+2 + GAP,
                    (CELL_SIZE/2)*(_model.nextFigureWidget().height()*2 +4)+3 + GAP);
    }
    
    private void drawGrid(Graphics g) {
        int height = getHeight();
        int width  = getWidth();
        g.setColor(GRID_COLOR); 
        for(int i = 1; i <= _model.glass().width()+1; i++)  // вертикальные линии
        {
            int x = GAP + CELL_SIZE*(i-1);
            g.drawLine(x, 0, x, CELL_SIZE*_model.glass().height());
        }
        for(int i = _model.glass().width()+2; i <= _model.nextFigureWidget().width()
                                                   +2+_model.glass().width(); i++) {
            int x = GAP + CELL_SIZE*(i-1);
            g.drawLine(x, CELL_SIZE*(_model.nextFigureWidget().height()+1),
                       x, CELL_SIZE);
        }
        int x = GAP + CELL_SIZE*(_model.glass().width()+1);
        int y = GAP + CELL_SIZE*_model.glass().height();
        g.drawLine(0, y, CELL_SIZE*_model.glass().width(), y);
        g.drawLine(0, 0, CELL_SIZE*_model.glass().width(), 0);
        y = (_model.nextFigureWidget().width()+1+_model.glass().width())*CELL_SIZE-GAP;
        g.drawLine(x, CELL_SIZE*(_model.nextFigureWidget().height()+1), y,
                   CELL_SIZE*(_model.nextFigureWidget().height()+1));
        g.drawLine(x, CELL_SIZE, y, CELL_SIZE);
    }
    
    @Override
    public void keyTyped(KeyEvent ke) {
    }

    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode() == KeyEvent.VK_UP) {         // вращаем фигуру
                _model.glass().currentFigure().turn();
            }
            else if(ke.getKeyCode() == KeyEvent.VK_DOWN) {  // перемещаемся вниз
                _model.glass().currentFigure().move(Direction.down());
            }
            else if(ke.getKeyCode() == KeyEvent.VK_LEFT) {  // перемещаемся влево
                _model.glass().currentFigure().move(Direction.left());
            }
            else if(ke.getKeyCode() == KeyEvent.VK_RIGHT) { // перемещаемся вправо
                _model.glass().currentFigure().move(Direction.right());;
            }
    }

    @Override
    public void keyReleased(KeyEvent ke) {
    }

    @Override
    public void figureMakedMove(FigureActionEvent e) {
        repaint();
    }

    @Override
    public void figureAreTurned(FigureActionEvent e) {
        repaint();
    }

    @Override
    public void figureAreFallen(FigureActionEvent e) {
        repaint();
    }

    @Override
    public void rowsArranged(GlassEvent e) {
        repaint();
    }
    
    public int width() {
        return _width;
    }
    
    public int height() {
        return _height;
    }
}
